package com.lykj.llw.box.utils

import android.app.Activity
import android.util.Log
import androidx.lifecycle.lifecycleScope
import com.blankj.utilcode.util.ActivityUtils
import com.blankj.utilcode.util.GsonUtils
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.SPUtils
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
import com.lykj.lib_base.base.BaseActivity
import com.lykj.lib_base.bus.FlowBus
import com.lykj.lib_base.constants.BConstants
import com.lykj.lib_base.internal.utils.PackageUtils
import com.lykj.lib_base.internal.utils.ToastUtils
import com.lykj.lib_base.net.http.RetrofitManager
import com.lykj.llw.box.data.model.LocalDownloadRecordModel
import com.tencent.mmkv.MMKV
import com.yqwb.gamebox.internal.inter.OnDownloadListener
import okhttp3.Call
import java.io.File
import java.util.concurrent.CopyOnWriteArrayList
import kotlin.collections.HashMap

/**
 * 下载管理器
 */
object DownloadManagerUtils {
    private val TAG = "DownloadManagerUtils"
    val mmkv = MMKV.defaultMMKV()
    var downloadRecords = CopyOnWriteArrayList<LocalDownloadRecordModel>()
    val mCalls = HashMap<Int, Call?>()

    //判断下载是否存在
    open fun judgementDownloadIsExit(gid: Int): Boolean {
        var isExist = false
        for ((_, r) in downloadRecords.withIndex()) {
            if (r.gameId == gid) {
                isExist = true
                break
            }
        }
        return isExist
    }

    open fun getCallFromGameId(gid: Int): Call? {
        return mCalls.get(gid)
    }

    //获取下载记录信息
    open fun getDownloadRecordInfo(gid: Int): LocalDownloadRecordModel? {
        var record: LocalDownloadRecordModel? = null
        for ((_, r) in downloadRecords.withIndex()) {
            if (r.gameId == gid) {
                record = r
                break
            }
        }
        return record;
    }

    @Synchronized
    open fun getDownloadInfo(): CopyOnWriteArrayList<LocalDownloadRecordModel> {
        return downloadRecords
    }

    //从本地获取下载历史记录
    @Synchronized
    open fun getDownloadInfoFromLocal(): CopyOnWriteArrayList<LocalDownloadRecordModel> {
        if (downloadRecords.isEmpty()) {
            val str = mmkv.decodeString("downloadRecords")
            if (!str.isNullOrBlank()) {
                downloadRecords = GsonUtils.fromJson(
                    str,
                    object : TypeToken<CopyOnWriteArrayList<LocalDownloadRecordModel>>() {}.type
                )
            }
        }

        downloadRecords.forEach {
            it.isManagerModel = false
        }

        //FIXME:检查apk文件是否存在,不存在则删除对应的下载记录
        return downloadRecords
    }

    //写入下载记录到本地
    open fun writeDownloadToLocal() {
        val str = GsonUtils.toJson(downloadRecords)
        mmkv.encode("downloadRecords", str)
    }

    //下载文件
    @Synchronized
    open fun downloadFile(
        activity: BaseActivity,
        url: String,
        _downloadInfo: LocalDownloadRecordModel
    ) {
        //构建下载实体
        if (judgementDownloadIsExit(_downloadInfo.gameId)) {
            if (getDownloadRecordInfo(_downloadInfo.gameId)?.status == 1) {
                Log.e(TAG, "下载文件已存在,直接安装")

                val path = "${_downloadInfo.path}/${_downloadInfo.gameId}.apk"
                val file = File(path)
                if (file.exists()) {
                    PackageUtils.installApk(
                        activity,
                        "${_downloadInfo.path}/${_downloadInfo.gameId}.apk"
                    )
                } else {
                    for ((index, m) in downloadRecords.withIndex()) {
                        if (m.gameId == _downloadInfo.gameId) {
                            downloadRecords.removeAt(index)
                            writeDownloadToLocal()
                        }
                    }
                }
                return
            } else {
                for ((index, m) in downloadRecords.withIndex()) {
                    if (m.gameId == _downloadInfo.gameId) {
                        getCallFromGameId(downloadRecords[index].gameId)?.cancel()
                        downloadRecords.removeAt(index)
                        writeDownloadToLocal()
                    }
                }
            }
        }

        downloadRecords.add(_downloadInfo)
        val call = RetrofitManager.instance.downFileCall(
            url,
            _downloadInfo.path,
            "${_downloadInfo.gameId}.apk",
            object : OnDownloadListener {
                override fun onSuccess() {
                    LogUtils.d("downFile:onSuccess")
                }

                override fun onFail() {
//                    ActivityUtils.getActivityList().last().runOnUiThread {
//                        ToastUtils.showShort(
//                            ActivityUtils.getActivityList().last(),
//                            "下载失败,请重试"
//                        )
//                    }
                    Log.e(TAG, "下载失败")
                }

                override fun onProgress(currentBytes: Float, totalBytes: Float, progress: Int) {
                    _downloadInfo.currentBytes = currentBytes
                    _downloadInfo.totalBytes = totalBytes
                    _downloadInfo.progress = progress

//                    if (ActivityUtils.getTopActivity().componentName.toString()
//                            .contains("GameDetailActivity") || System.currentTimeMillis() - mCurrentTime > 850
//                    ) {
                    FlowBus.withStick<LocalDownloadRecordModel>(BConstants.BUS_KEY.DOWNLOAD_REFRESH)
                        .post(
                            (ActivityUtils.getActivityList()
                                .last() as BaseActivity).lifecycleScope,
                            _downloadInfo
                        )

//                        mCurrentTime = System.currentTimeMillis()
//                    }

                    if (100 == progress) {
                        _downloadInfo.status = 1

                        FlowBus.withStick<LocalDownloadRecordModel>(BConstants.BUS_KEY.DOWNLOAD_REFRESH)
                            .post(
                                (ActivityUtils.getActivityList()
                                    .last() as BaseActivity).lifecycleScope,
                                _downloadInfo
                            )

                        val instanceName = "@${
                            Integer.toHexString(
                                System.identityHashCode(
                                    _downloadInfo
                                )
                            )
                        }"
                        Log.e(TAG, "${_downloadInfo.gameId}==${instanceName}::$progress")
                    }

                    writeDownloadToLocal()
                }
            })

//        _downloadInfo.call = call
        mCalls.put(_downloadInfo.gameId, call)
    }
}